package com.bestcem.xm.survey.service.reportHandler.type;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.service.reportHandler.BaseReportHandler;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.bestcem.xm.survey.util.SurveyConstant.SCORE_RULE_ALL_RIGHT;

@Component
public class MultipleScoreHandler implements BaseReportHandler {

    @Override
    public Double getMaxScore(JSONObject question, JSONArray scoreRule) {
        if (question == null || question.getJSONArray("items") == null) {
            return 0d;
        }
        JSONArray items = question.getJSONArray("items");
        JSONObject scoreGidDict = getScoreGidDict(scoreRule);
        List<Double> gte0score = new ArrayList<>();
        List<Double> lt0score = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            JSONObject item = items.getJSONObject(i);
            String oGid = item.getString("gid");
            Double score = scoreGidDict.getDouble(oGid);
            score = score == null ? 0d : score;
            if (score >= 0) {
                gte0score.add(score);
            } else {
                lt0score.add(score);
            }
        }

        if (!CollectionUtils.isEmpty(gte0score)) {
            return convertFloat(gte0score.stream()
                .mapToDouble(Double::doubleValue)
                .sum());
        } else {
            return convertFloat(Collections.max(lt0score));
        }
    }

    @Override
    public Double getScore(JSONObject question, Object answers, JSONArray scoreRule, JSONObject scoreConfig) {
        double score = 0.0;
        JSONObject scoreGidDict = getScoreGidDict(scoreRule);
        Integer scoreConf = scoreConfig.getInteger(question.getString("gid"));
        if ("image_select".equals(question.getString("custom_qtype"))
            || !SCORE_RULE_ALL_RIGHT.equals(scoreConf)
            || !checkAnswerAllRight(scoreGidDict, ((JSONArray)answers))) {
            if (answers != null) {
                for (int i = 0; i < ((JSONArray)answers).size(); i++) {
                    JSONArray answer = ((JSONArray)answers).getJSONArray(i);
                    if (answer != null) {
                        String oGid = answer.getString(0);
                        score += convertFloat(scoreGidDict.getDouble(oGid));
                    }
                }
            }
        }

        return convertFloat(score);
    }

    @Override
    public List<String> getQuestionTypeValue() {
        return Collections.singletonList("multiple");
    }

    private boolean checkAnswerAllRight(JSONObject scoreGidDict, JSONArray answers) {
        // 判断是否为 负值
        // {'3': -1.0, '4': -2.0, '6': -3.0, '7': -4.0}
        List<Boolean> allLtZero = new ArrayList<>();
        List<String> keys = new ArrayList<>(scoreGidDict.keySet());
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Double value = scoreGidDict.getDouble(key);
            if (0 != value) {
                allLtZero.add(value < 0);
            }
        }
        if (CollectionUtils.isNotEmpty(allLtZero) && allLtZero.stream()
            .allMatch(Boolean::booleanValue)) {
            return false;
        }
        // 设置的 正确的选项 分数 > 0
        List<String> allScoreGteZeroGids = new ArrayList<>();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Double value = scoreGidDict.getDouble(key);
            if (0 < value) {
                allScoreGteZeroGids.add(key);
            }
        }
        // 答案 提交的选项 gid
        // [[3], [4], [6], [7]]
        List<String> answersGids = new ArrayList<>();
        for (int i = 0; i < answers.size(); i++) {
            JSONArray it = answers.getJSONArray(i);
            answersGids.add(it.getString(0));
        }
        boolean flag = false;
        if (CollectionUtils.isEmpty(allScoreGteZeroGids) || CollectionUtils.isEmpty(answersGids)
            || allScoreGteZeroGids.size() != answersGids.size()) {
            flag = true;
        }
        // 若答案gid 和 配置的全对gid 有差异 则次题答案非全对
        List<Boolean> allRight = answersGids.stream().map(allScoreGteZeroGids::contains).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(allRight) || !allRight.stream().allMatch(Boolean::booleanValue)) {
            flag = true;
        }
        return flag;
    }
}
